Sometimes a computational problem can be divided into pieces in a way that allows a system to work on more than one piece at a time. For example, concurrent computing simultaneously carries out multiple computing tasks, such as multiple threads or multiple processes. Similarly, parallel computing systems carry out multiple instructions simultaneously. Parallel computing may be viewed as an example of concurrent computing, and the distinction between them is not critical here.
Various tools and techniques are used to coordinate the pieces of a divided computational problem. In particular, transactional memory may be used to control access to shared memory. Transactional memory supports a way to abstractly express what memory operations operate with a transactional behavior. In some transactional memory implementations, code in a transaction executes a series of reads and writes to shared memory which appear from outside the transaction to happen atomically. That is, either all of the code in a transaction completes (transaction succeeded), or else work done by the code before the transaction fails is undone, so the view from outside the transaction is that none of the code completed (transaction failed).
In some situations, code is initially designed and written to run on a transactional memory system, while in other situations the possibility of running particular code on a transactional memory implementation arises after that code has already been designed and written. Some code is also less amenable to transactional execution than other code. For example, it may be difficult or impossible to undo work done by code that transmits data over a network or code that changes the state of a peripheral device.